package com.guigu.pd.dispatch.jobs;

import com.guigu.pd.dispatch.entity.ScheduleJobEntity;
import com.guigu.pd.dispatch.entity.ScheduleJobLogEntity;
import com.guigu.pd.dispatch.service.ScheduleJobLogService;
import com.guigu.pd.dispatch.task.DispatchTask;
import com.guigu.pd.dispatch.utils.ExceptionUtils;
import com.guigu.pd.dispatch.utils.IdUtils;
import com.guigu.pd.dispatch.utils.ScheduleUtils;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.lang.reflect.Method;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;


/**
 * 自定义Job
 */
@Component
public class ScheduleJob extends QuartzJobBean implements ApplicationContextAware {

    private Logger logger = LoggerFactory.getLogger(getClass());

    public static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    //任务触发时执行此方法
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {

        ScheduleJobEntity scheduleJob = (ScheduleJobEntity) context.getMergedJobDataMap().get(ScheduleUtils.JOB_PARAM_KEY);
        System.out.println(new Date() + "定时任务开始执行...,定时任务id：" + scheduleJob.getId());


        //记录定时任务相关的日志信息
        ScheduleJobLogEntity logEntity = new ScheduleJobLogEntity();
        logEntity.setId(IdUtils.get());
        logEntity.setJobId(scheduleJob.getId());
        logEntity.setBeanName(scheduleJob.getBeanName());
        logEntity.setParams(scheduleJob.getParams());
        logEntity.setCreateDate(new Date());

        long startTime = System.currentTimeMillis();
        try {

//            String[] beanDefinitionNames = ScheduleJob.context.getBeanDefinitionNames();
//            for (String beanDefinitionName : beanDefinitionNames) {
//                System.out.println(beanDefinitionName);
//            }


            //通过反射调用目标，在目标对象中封装智能调度核心逻辑
            logger.info("定时任务开始执行...,定时任务id：" + scheduleJob.getId());
            String beanName = scheduleJob.getBeanName();

            Object target = ScheduleJob.context.getBean(beanName);

            Method method = target.getClass().getDeclaredMethod("run", String.class, String.class, String.class, String.class);
            //通过反射调用目标方法，完成智能调度
            method.invoke(target, scheduleJob.getBusinessId(), scheduleJob.getParams(), scheduleJob.getId(), logEntity.getId());


            logEntity.setStatus(1);
        } catch (Exception e) {
            logEntity.setStatus(0);
            logEntity.setError(ExceptionUtils.getErrorStackTrace(e));
            logger.error("定时任务执行失败...,定时任务id：" + scheduleJob.getId());
        } finally {
            int times = (int) (System.currentTimeMillis() - startTime);
            logEntity.setTimes(times);//耗时


            //添加定时任务日志信息
            ScheduleJobLogService scheduleJobLogService = ScheduleJob.context.getBean(ScheduleJobLogService.class);
            scheduleJobLogService.save(logEntity);
        }


    }
}
